package com.ycy;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.ConverterKeyBuild;
import com.alibaba.excel.converters.ReadConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty;
import com.alibaba.excel.util.ConverterUtils;
import com.alibaba.excel.util.StringUtils;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

public class GenericDataListener44 extends AnalysisEventListener<RaInfoV2ForVillageUploadForCommonUploadExcelByNameMulti> {

    private List<RaInfoV2ForVillageUploadForCommonUploadExcelByNameMulti> dataList = new ArrayList<>();

    public static final AtomicInteger ai = new AtomicInteger();

    Map<Integer, ReadCellData<?>> lastHeadMap = new HashMap<>();

    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext analysisContext) {

        int i = ai.incrementAndGet();

        if (ExcelDemo44.lastHeadRow - 1 == i) {
            lastHeadMap = headMap;
            return;
        }

        if (ExcelDemo44.lastHeadRow == i) {
            //合并3到4行

            for (Map.Entry<Integer, ReadCellData<?>> integerReadCellDataEntry : headMap.entrySet()) {
                ReadCellData<?> cellData = integerReadCellDataEntry.getValue();
                Integer key = integerReadCellDataEntry.getKey();

                if (cellData.getType() == CellDataTypeEnum.EMPTY) {
                    ReadCellData<?> readCellData = lastHeadMap.get(key);
                    if (readCellData.getType() != CellDataTypeEnum.EMPTY) {
                        headMap.put(key, readCellData);
                    }
                } else {
                    // 从上级查找表头
                    ReadCellData<?> readCellData = lastHeadMap.get(key);
//                    if (key == 0 && readCellData.getType() == CellDataTypeEnum.EMPTY) {
//                        throw new RuntimeException("加载表头异常:上级表头第一列内容不能为空");
//                    }
                    if (readCellData.getType() != CellDataTypeEnum.EMPTY) {
                        cellData.setStringValue(readCellData.getStringValue() + ":::" + cellData.getStringValue());
                    } else {
                        // 对应的上级表头为空,就往前查找
                        int keyIndex = key - 1;
                        ReadCellData<?> leastReadCellData = lastHeadMap.get(keyIndex);
                        while (keyIndex >= 0 && leastReadCellData.getType() == CellDataTypeEnum.EMPTY) {
                            leastReadCellData = lastHeadMap.get(--keyIndex);
                        }
                        if (leastReadCellData != null && leastReadCellData.getType() != CellDataTypeEnum.EMPTY){
                            cellData.setStringValue(leastReadCellData.getStringValue() + ":::" + cellData.getStringValue());
                        }
                    }
                }
            }

            // 改写excel 到 实体的路由配置 TODO 没有办法了。 因为 在读取到表头行的时候实体类的字段 已经跟 读取的表头绑定好了

            Map<Integer, String> dataMap = ConverterUtils.convertToStringMap(headMap, analysisContext);

            ExcelReadHeadProperty excelHeadPropertyData = analysisContext.readSheetHolder().excelReadHeadProperty();
            Map<Integer, Head> headMapData = excelHeadPropertyData.getHeadMap();

            Map<Integer, Head> tmpHeadMap = new HashMap<Integer, Head>(headMapData.size() * 4 / 3 + 1);

            for (Map.Entry<Integer, Head> entry : headMapData.entrySet()) {
                Head headData = entry.getValue();
                if (headData.getForceIndex() || !headData.getForceName()) {
                    tmpHeadMap.put(entry.getKey(), headData);
                    continue;
                }
                List<String> headNameList = headData.getHeadNameList();
                String headName = headNameList.get(headNameList.size() - 1);
                for (Map.Entry<Integer, String> stringEntry : dataMap.entrySet()) {
                    if (stringEntry == null) {
                        continue;
                    }
                    String headString = stringEntry.getValue();
                    Integer stringKey = stringEntry.getKey();
                    if (StringUtils.isEmpty(headString)) {
                        continue;
                    }
                    if (analysisContext.currentReadHolder().globalConfiguration().getAutoTrim()) {
                        headString = headString.trim();
                    }
                    if (headName.equals(headString)) {
                        headData.setColumnIndex(stringKey);
                        tmpHeadMap.put(stringKey, headData);
                        break;
                    }
                }
            }
            excelHeadPropertyData.setHeadMap(tmpHeadMap);

        }

        invokeHeadMap(ConverterUtils.convertToStringMap(headMap, analysisContext), analysisContext);
    }

    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        TreeMap<Integer, String> obj = new TreeMap<>(headMap);
        for (Map.Entry<Integer, String> integerStringEntry : obj.entrySet()) {
            System.out.println(String.format("header -> %s : %s", integerStringEntry.getKey(), integerStringEntry.getValue()));
        }
        System.out.println("==============================");
    }

    @Override
    public void invoke(RaInfoV2ForVillageUploadForCommonUploadExcelByNameMulti data, AnalysisContext context) {
        dataList.add(data);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 读取完成后的操作
        System.out.println("所有数据读取完成！");
    }

    public List<RaInfoV2ForVillageUploadForCommonUploadExcelByNameMulti> getDataList() {
        return dataList;
    }
}